css+gsap+vue实现背景图标放烟花/天女散花/随机发散效果

您所在的位置:网站首页 撒花动画 ios css+gsap+vue实现背景图标放烟花/天女散花/随机发散效果

css+gsap+vue实现背景图标放烟花/天女散花/随机发散效果

2023-09-17 15:31| 来源: 网络整理| 查看: 265

效果 前言

gsap 基础这里不做多详述,可以先学习此文:

《 gsap.js 的简单应用——页面加载文字弹出效果》

了解 gsap.to() 的使用方法。

实现 基础图标

基础图标即——每个小图标,有了基础图标,我们再对其复制做出随机的动画。

基础图标可以是 .png 、.svg 等,不做限制,但是要统一 absolute 放置在页面动画产生点:

// ... 嵌入图标节点

在最外层 icons 包裹所有基础图标以及复制出的节点,基础图标采用 display: none; 防止显示,并加以双居中 + 初始 opacity: 0; (在之前的文章中,我们说过了 autoAlpha 比只使用 opacity 性能要佳,使用 opacity: 0; + autoAlpha 动画可以达到更好的效果)。

.vue { position: absolute; top: 50%; left: 50%; transform: translate(-50%, -50%) scale(0); opacity: 0; z-index: -1; } 核心动画

动画是一个异步的过程,为了把握,我们往往在 gsap.to() 的第三个参数中 onComplete 配置完成要做的事情,同时每一个动画过程都创建一个 Promise + 全部动画 Promise.all() 的形式执行。

如果你还不明白为什么要这么做,你可以通过此文来了解:

《 vue + gsap 实现 vuetelemetry 动画轮播图》

有了以上的基础,我们便可以写出动画核心变换如下:

animation(node) { const width = this.width; const height = this.height; return new Promise((resolve, reject) => { try { const v = gsap.to(node, 0.3, { x: 2 * (Math.random() - 0.5) * width, y: 2 * (Math.random() - 0.5) * height, autoAlpha: Math.random() * 0.4 + 0.2, scale: Math.random() * 0.5 + 0.3, rotate: 2 * (Math.random() - 0.5) * 40, }); setTimeout(() => { v.reverse().then(() => { resolve(); }); }, 3000); } catch (e) { reject(e); } }); },

这是一个相比之前文章十分简单的动画变换,在之前的文章中,我们没有使用过反向执行 reverse() 与 .then() :

reverse() :反向执行动画。必须要先拿到 gsap.to() 返回的渐变实体类 Tween 才能执行。.then() :动画结束后需要做的事情。优点是该函数晚于 onComplete ,缺点是不能使用 this 。 动画主函数 popIcons(className) { const icons = this.$refs.icons; const target = this.$refs[className]; target.style = ""; target.classList.add(className); const targetCopy = target.cloneNode(true); const newNodeList = []; for (let i = this.count; i--; ) { let node = targetCopy.cloneNode(true); newNodeList.push(node); icons.appendChild(node); } const animationTask = []; document.getElementsByClassName(className).forEach((node) => { animationTask.push(this.animation(node)); }); Promise.all(animationTask).then(() => { newNodeList.forEach((node) => { node.parentNode.removeChild(node); }); }); },

下面详解实现逻辑:

const icons = this.$refs.icons; const target = this.$refs[className]; target.style = ""; target.classList.add(className);

↑ 选取所有图标外层父节点 icons 与基础图标节点(也就是被隐藏的包裹图标的节点),之后清除 style (清除了 display: none; )使节点可显示,并添加好我们在上文中定义的类。

这个类有两个作用,第一是 absolute + 双居中,并且全透明,作为动画的初始状态;第二是方便 gsap.to() 元素选择器选择节点。

const targetCopy = target.cloneNode(true); const newNodeList = []; for (let i = this.count; i--; ) { let node = targetCopy.cloneNode(true); newNodeList.push(node); icons.appendChild(node); }

↑ 克隆节点,并把所有新添加的节点添加入父节点 icons 内。

注:相同节点不能被多次添加,只能不断克隆新节点再添加。

const animationTask = []; document.getElementsByClassName(className).forEach((node) => { animationTask.push(this.animation(node)); }); Promise.all(animationTask).then(() => { newNodeList.forEach((node) => { node.parentNode.removeChild(node); }); });

↑ 最基础的 Promise.all() 处理多动画流程,在之前的文章我们已经了解过了。

循环运行

核心流程已经介绍完了,为了实现不同图标、循环运行,还需要两个条件:

使用图标名列表,并在以上基础之上添加多个图标的基础节点,按顺序遍历图标名列表即可在上一次的动画 Promise 成功后再重复调用本函数,形成无限回调 总结

GSAP 系列也写过三篇文章了,核心无外乎 gsap.to() 和 gsap.from() ,一款比 jQuery 性能还要好的动画库,所带来的快乐和收益是非常大的。



【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3